/**
 * 
 */
package edu.umd.clip.lm.model;

import edu.umd.clip.lm.factors.FactorTuple;
import edu.umd.clip.lm.util.tree.*;
import edu.umd.clip.lm.util.*;
import org.w3c.dom.*;
import java.io.*;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class HFT<T extends XMLizable> extends XMLizable {
	public static final String XML_ELEMENT_NAME = "hft";
	
	private BinaryTree<T> tree;
	private int numLeaves = -1;
	/**
	 * @return the tree
	 */
	public BinaryTree<T> getTree() {
		return tree;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.util.XMLizable#createXML(org.w3c.dom.Document)
	 */
	@Override
	public Element createXML(Document doc) {
		Element element = doc.createElement(XML_ELEMENT_NAME);
		element.appendChild(tree.createXML(doc));
		return element;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.util.XMLizable#getElementName()
	 */
	@Override
	public String getElementName() {
		return XML_ELEMENT_NAME;
	}

	/**
	 * @param xmlnode
	 */
	public HFT(Element xmlnode) {
		assert(xmlnode.getTagName().equals(XML_ELEMENT_NAME));
		Element elem = XMLUtils.getFirstElementByTagName(xmlnode, BinaryTree.XML_ELEMENT_NAME);
		setTree(new BinaryTree<T>(elem));
	}
	
	public HFT(BinaryTree<T> tree) {
		setTree(tree);
	}

	public int getNumLeaves() {
		return numLeaves;
	}

	private void setTree(BinaryTree<T> tree) {
		this.tree = tree;
		int size = 0;
		for(BinaryTreeIterator<T> i = tree.getLeafIterator(); i.hasNext(); ++size, i.next()) {}
		numLeaves = size;
	}
	
	public static void dumpTree(BinaryTree<HFTPayload> root, String filename) {
		try {
			FileWriter treeOutput = new FileWriter(filename);
			GraphvizOutput graph = new GraphvizOutput("HFT") {

				@Override
				protected <T> String getText(T payload) {
					HFTPayload p = (HFTPayload) payload;
					if (p.tuple == 0) {
						return "";
					}
					return FactorTuple.toStringNoNull(p.tuple) + "\n" + p.prefix.toString();
				}
				
			};
			treeOutput.write(graph.getOutput(root));
			treeOutput.close();
		} catch(IOException e) {
			e.printStackTrace();
		}
	}

}
